package com.cyf.filmDownload.main;

import com.cyf.filmDownload.common.util.CollUtil;
import com.cyf.filmDownload.config.AppConfig;
import com.cyf.filmDownload.film.entity.DownloadResult;
import com.cyf.filmDownload.film.entity.FilmDetail;
import com.cyf.filmDownload.film.entity.SearchResult;
import com.cyf.filmDownload.film.exception.FilmException;
import com.cyf.filmDownload.film.service.AbstractFilmService;
import com.cyf.filmDownload.film.service.impl.NaiChaFilmService;
import com.cyf.filmDownload.m3u8.core.M3u8DownloadUtil;
import com.cyf.filmDownload.okhttp.HttpUtil;
import okhttp3.Response;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


public class AppMain {

    private static Map<String, AbstractFilmService> serviceMap = new LinkedHashMap<>();

    static {
        serviceMap.put("奶茶86", new NaiChaFilmService());
    }

    public static void main(String[] args) {
        String searchParam = getInput("请输入需要搜索的影视名称：");
        // 搜索
        List<SearchResult> searchResultList = searchFilmInfo(searchParam);
        // 获取下载列表
        List<DownloadResult> downloadList = getDownloadFilm(searchResultList);
        // 下载
        downloadFilm(downloadList);
    }

    public static void downloadFilm(List<DownloadResult> downloadList) {
        for (DownloadResult downloadResult : downloadList) {
            // 网站会有多个播放源，测试哪个播放源正常则下载
            Map<Integer, List<FilmDetail>> collect = downloadResult.getFilmDetails().stream().collect(Collectors.groupingBy(FilmDetail::getFilmIndex));
            for (Map.Entry<Integer, List<FilmDetail>> entry : collect.entrySet()) {
                Integer filmIndex = entry.getKey();
                List<FilmDetail> filmDetailList = entry.getValue();
                String downloadName = downloadResult.getType() == 1
                        ? downloadResult.getFilmName()
                        : downloadResult.getFilmName() + "第" + filmIndex + "集";
                System.out.println("开始下载" + downloadName);

                for (FilmDetail detail : filmDetailList) {
                    AbstractFilmService service = serviceMap.get(detail.getServiceName());
                    String m3u8Url = service.getM3u8Url(detail.getFileViewUrl());
                    // 测试播放源
                    boolean isOk = false;
                    try (Response response = HttpUtil.get(m3u8Url)) {
                        isOk = response.isSuccessful();
                    } catch (Exception e) {
                        System.out.println(m3u8Url + "播放源异常");
                    }
                    if (isOk) {
                        System.out.println("m3u8Url: " + m3u8Url);
                        String downloadPath = downloadResult.getType() == 1
                                ? Paths.get(AppConfig.videoDownloadDir, downloadName + ".mp4").toString()
                                : Paths.get(AppConfig.videoDownloadDir, downloadResult.getFilmName(), downloadName + ".mp4").toString();
                        M3u8DownloadUtil.download(m3u8Url, downloadPath);
                        break;
                    }
                }
            }
        }
    }

    public static List<DownloadResult> getDownloadFilm(List<SearchResult> searchResultList) {
        List<Integer> filmIndexList = getIndexList("请输入需要下载的影视序号：").stream().map(ele -> ele - 1).collect(Collectors.toList());
        boolean validInput = filmIndexList.stream().allMatch(ele -> ele >= 0 && ele < searchResultList.size());
        while (!validInput) {
            System.out.println("输入有误，请重新输入：");
            filmIndexList = getIndexList(getInput("请输入需要下载的影视序号：")).stream().map(ele -> ele - 1).collect(Collectors.toList());
            validInput = filmIndexList.stream().allMatch(ele -> ele >= 0 && ele < searchResultList.size());
        }

        List<DownloadResult> downloadResultList = new ArrayList<>();
        for (Integer filmIndex : filmIndexList) {
            SearchResult searchResult = searchResultList.get(filmIndex);
            searchResult.printFilmDetail();
            List<FilmDetail> filmDetails = searchResult.getFilmDetails();
            if (searchResult.getType() == 1) { // 电影
                boolean isConfirm = isConfirm("请确认是否下载" + searchResult.getFilmName() + "？(y/n)");
                if (isConfirm) {
                    DownloadResult downloadResult = new DownloadResult();
                    downloadResult.setFilmName(searchResult.getFilmName());
                    downloadResult.setFilmDetails(filmDetails);
                    downloadResult.setType(searchResult.getType());
                    downloadResultList.add(downloadResult);
                } else {
                    System.out.println(searchResult.getFilmName() + "下载取消");
                }
            } else { // 电视剧
                List<Integer> detailIndexList = getIndexList("请输入需要下载的" + searchResult.getFilmName() + "集数序号：");
                System.out.println("请确认需要下载的影视集数序号：" + detailIndexList);
                boolean isConfirm = isConfirm("是否确认下载？(y/n)");
                if (isConfirm) {
                    DownloadResult downloadResult = new DownloadResult();
                    downloadResult.setFilmName(searchResult.getFilmName());
                    downloadResult.setType(searchResult.getType());
                    downloadResult.setFilmDetails(filmDetails.stream().filter(filmDetail -> detailIndexList.contains(filmDetail.getFilmIndex())).collect(Collectors.toList()));
                    downloadResultList.add(downloadResult);
                } else {
                    System.out.println(searchResult.getFilmName() + "下载取消");
                }
            }
        }
       return downloadResultList;
    }

    public static boolean isConfirm(String msg) {
        return "y".equalsIgnoreCase(getInput(msg));
    }

    public static List<Integer> getIndexList(String msg) {
        String input = getInput(msg);
        if (input.contains("-")) {
            String[] split = input.split("-");
            int start = Integer.parseInt(split[0]);
            int end = Integer.parseInt(split[1]);
            return IntStream.rangeClosed(start, end).boxed().collect(Collectors.toList());
        } else if (input.contains(",")) {
            String[] split = input.split(",");
            return Arrays.stream(split).map(Integer::parseInt).collect(Collectors.toList());
        } else {
            return Collections.singletonList(Integer.parseInt(input));
        }
    }
    public static List<SearchResult> searchFilmInfo(String searchParam) {
        List<SearchResult> searchResultList = new ArrayList<>();
        for (Map.Entry<String, AbstractFilmService> entry : serviceMap.entrySet()) {
            String serviceName = entry.getKey();
            AbstractFilmService service = entry.getValue();
            List<SearchResult> searchResults = service.searchFilmInfo(searchParam);
            if (CollUtil.isNotEmpty(searchResults)) {
                searchResults.forEach(ele -> ele.getFilmDetails().forEach(filmDetail -> filmDetail.setServiceName(serviceName)));
                searchResultList.addAll(searchResults);
            }
        }
        if (CollUtil.isEmpty(searchResultList)) {
            throw new FilmException("未找到相关影视");
        }

        // 多个搜索源整合结果
        List<SearchResult> resList = new ArrayList<>();
        Map<String, List<SearchResult>> collect = searchResultList.stream().collect(Collectors.groupingBy(SearchResult::getFilmName));
        for (Map.Entry<String, List<SearchResult>> entry : collect.entrySet()) {
            SearchResult copy = new SearchResult();
            List<SearchResult> list = entry.getValue();
            copy.setFilmName(entry.getKey());
            copy.setFilmDesc(list.get(0).getFilmDesc());
            copy.setType(list.get(0).getType());
            copy.setActor(list.get(0).getActor());
            copy.setFilmDetails(list.stream().flatMap(ele -> ele.getFilmDetails().stream()).collect(Collectors.toList()));
            copy.getFilmDetails().sort(Comparator.comparingInt(FilmDetail::getFilmIndex));
            resList.add(copy);
        }

        System.out.println("--------------------------搜索结果如下--------------------------");
        for (int i = 0; i < resList.size(); i++) {
            SearchResult searchResult = resList.get(i);
            System.out.println((i + 1) + "  " + searchResult.getFilmName());
            System.out.println("主演：" + searchResult.getActor());
            System.out.println("描述：" + searchResult.getFilmDesc());
            System.out.println();
        }
        return resList;
    }

    public static String getInput(String msg) {
        System.out.println(msg);
        return new Scanner(System.in).nextLine();
    }
}
